home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 2
/
Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso
/
Aminet
/
comm
/
term
/
term34Source.lha
/
termClip.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-16
|
11KB
|
638 lines
/*
** termClip.c
**
** Clipboard support routines
**
** Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
** All Rights Reserved
*/
#include "termGlobal.h"
STATIC struct IFFHandle *ClipHandle;
STATIC STRPTR ClipBuffer,
ClipIndex;
STATIC LONG ClipSize,
ClipLength;
/* ClipServer():
*
* Quiet background process which saves data to the clipboard
* or fills a buffer with fresh clipboard data.
*/
VOID __saveds
ClipServer()
{
struct IOClipReq __aligned ClipRequest;
/* Clear the request. */
memset(&ClipRequest,0,sizeof(struct IOClipReq));
/* Open the clipboard.device, we will not use the
* IORequest to do any IO operations on it, but
* rather to keep clipboard.device available
* when needed.
*/
if(!OpenDevice("clipboard.device",PRIMARY_CLIP,(struct IORequest *)&ClipRequest,NULL))
{
if(ClipPort = CreateMsgPort())
{
ULONG Mask;
struct Message *ClipMsg;
UBYTE *Buffer;
BYTE Terminated = FALSE;
Signal(ThisProcess,SIG_HANDSHAKE);
while(!Terminated)
{
Mask = Wait(SIG_KILL | PORTMASK(ClipPort));
if(Mask & SIG_KILL)
Terminated = TRUE;
if(Mask & PORTMASK(ClipPort))
{
while(ClipMsg = GetMsg(ClipPort))
{
Buffer = ClipMsg -> mn_Node . ln_Name;
if(Buffer[0])
SaveClip(Buffer,strlen(Buffer));
else
{
WORD Len = LoadClip(Buffer,256);
Buffer[Len] = 0;
}
ReplyMsg(ClipMsg);
}
}
}
DeleteMsgPort(ClipPort);
}
CloseDevice((struct IORequest *)&ClipRequest);
}
Forbid();
ClipProcess = NULL;
Signal(ThisProcess,SIG_HANDSHAKE);
}
/* CloseClip():
*
* Close clipboard handle, stop reading.
*/
VOID
CloseClip()
{
if(ClipHandle)
{
CloseIFF(ClipHandle);
if(ClipHandle -> iff_Stream)
CloseClipboard((struct ClipboardHandle *)ClipHandle -> iff_Stream);
FreeIFF(ClipHandle);
ClipHandle = NULL;
}
if(ClipBuffer)
{
FreeVec(ClipBuffer);
ClipBuffer = NULL;
}
}
/* GetClip(STRPTR Buffer,WORD Len,BYTE Filter):
*
* Read text data from clipboard and put it into the supplied buffer.
*/
WORD
GetClip(STRPTR Buffer,WORD Len,BYTE Filter)
{
WORD BytesPut = 0;
/* Is the read buffer already exhausted? */
if(!ClipLength)
{
/* Is there still any data to read? */
if(ClipSize)
{
WORD Size = MIN(ClipSize,1024);
/* Try to read the data and return failure if necessary. */
if(ReadChunkBytes(ClipHandle,ClipBuffer,Size) != Size)
return(-1);
else
{
ClipSize -= Size;
ClipLength = Size;
ClipIndex = ClipBuffer;
}
}
else
{
/* We just parsed a single chunk, now go on and
* look for another one.
*/
if(!ParseIFF(ClipHandle,IFFPARSE_SCAN))
{
struct ContextNode *ContextNode = CurrentChunk(ClipHandle);
if(ContextNode -> cn_Type == ID_FTXT)
{
WORD Size;
ClipSize = ContextNode -> cn_Size;
Size = MIN(ClipSize,1024);
if(ReadChunkBytes(ClipHandle,ClipBuffer,Size) != Size)
return(-1);
else
{
ClipSize -= Size;
ClipLength = Size;
ClipIndex = ClipBuffer;
}
}
else
return(-1);
}
else
return(-1);
}
}
/* The following loop processes the contents of
* the clipboard buffer read. Special characters
* such as LF and CR will be converted according
* to the current settings if enabled. No bytes
* will be lost, though.
*/
while(ClipLength && BytesPut < Len)
{
if(*ClipIndex == '\n')
{
if(Filter)
{
*Buffer++ = *ClipIndex++;
BytesPut++;
ClipLength--;
}
else
{
switch(Config -> TerminalConfig -> SendLF)
{
case LF_IGNORE:
ClipIndex++;
ClipLength--;
break;
case LF_ASLFCR:
if(BytesPut + 2 <= Len)
{
*Buffer++ = '\n';
*Buffer++ = '\r';
BytesPut += 2;
ClipLength--;
ClipIndex++;
}
else
return(BytesPut);
break;
case LF_ASLF:
*Buffer++ = *ClipIndex++;
BytesPut++;
ClipLength--;
break;
}
}
}
else
{
if(*ClipIndex == '\r')
{
if(Filter)
{
ClipIndex++;
ClipLength--;
}
else
{
switch(Config -> TerminalConfig -> SendCR)
{
case CR_IGNORE:
ClipIndex++;
ClipLength--;
break;
case CR_ASCRLF:
if(BytesPut + 2 <= Len)
{
*Buffer++ = '\r';
*Buffer++ = '\n';
BytesPut += 2;
ClipLength--;
ClipIndex++;
}
else
return(BytesPut);
break;
case CR_ASCR:
*Buffer++ = *ClipIndex++;
BytesPut++;
ClipLength--;
break;
}
}
}
else
{
register UBYTE c = *ClipIndex++;
ClipLength--;
if(!Filter || IsPrintable[c])
{
*Buffer++ = c;
BytesPut++;
}
}
}
}
return(BytesPut);
}
/* OpenClip():
*
* Open the clipboard for sequential reading.
*/
BYTE
OpenClip(LONG Unit)
{
BYTE Error;
CloseClip();
if(ClipBuffer = (STRPTR)AllocVec(1024,MEMF_ANY))
{
if(ClipHandle = AllocIFF())
{
if(ClipHandle -> iff_Stream = (ULONG)OpenClipboard(Unit))
{
InitIFFasClip(ClipHandle);
if(!OpenIFF(ClipHandle,IFFF_READ))
{
if(!StopChunk(ClipHandle,ID_FTXT,ID_CHRS))
{
if(!ParseIFF(ClipHandle,IFFPARSE_SCAN))
{
struct ContextNode *ContextNode = CurrentChunk(ClipHandle);
if(ContextNode -> cn_Type == ID_FTXT)
{
ClipSize = ContextNode -> cn_Size;
ClipLength = 0;
return(CLIPERR_NONE);
}
else
Error = CLIPERR_NOTEXT;
}
else
Error = CLIPERR_NOTEXT;
}
else
Error = CLIPERR_IFF;
}
else
Error = CLIPERR_OPEN;
}
else
Error = CLIPERR_OPEN;
}
else
Error = CLIPERR_MEM;
}
else
Error = CLIPERR_MEM;
CloseClip();
return(Error);
}
/* GetClipContents(LONG Unit,APTR *Buffer,LONG *Size):
*
* Merge text contents of the clipboard into a single string.
*/
BYTE
GetClipContents(LONG Unit,APTR *Buffer,LONG *Size)
{
struct IFFHandle *Handle;
LONG Bytes = 0;
APTR Store = NULL;
if(Handle = AllocIFF())
{
if(Handle -> iff_Stream = (ULONG)OpenClipboard(Unit))
{
InitIFFasClip(Handle);
if(!OpenIFF(Handle,IFFF_READ))
{
if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
{
struct ContextNode *Node;
while(!ParseIFF(Handle,IFFPARSE_SCAN))
{
Node = CurrentChunk(Handle);
if(Node -> cn_Type == ID_FTXT)
Bytes += Node -> cn_Size;
}
}
CloseIFF(Handle);
}
if(Bytes)
{
if(!OpenIFF(Handle,IFFF_READ))
{
if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
{
if(Store = AllocVec(Bytes,MEMF_ANY))
{
STRPTR Index = Store;
LONG BytesRead = 0;
struct ContextNode *Node;
while(!ParseIFF(Handle,IFFPARSE_SCAN) && BytesRead < Bytes)
{
Node = CurrentChunk(Handle);
if(Node -> cn_Type == ID_FTXT)
{
LONG Count = Node -> cn_Size;
if(BytesRead + Count > Bytes)
Count = Bytes - BytesRead;
if(Count > 0)
{
if((Count = ReadChunkBytes(Handle,Index,Count)) > 0)
{
Index += Count;
BytesRead += Count;
}
}
}
}
Bytes = BytesRead;
}
}
CloseIFF(Handle);
}
}
CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
}
FreeIFF(Handle);
}
if(Store && !Bytes)
{
FreeVec(Store);
Store = NULL;
}
*Buffer = Store;
*Size = Bytes;
return((BYTE)(Store != NULL));
}
/* AddClip(STRPTR Buffer,LONG Size):
*
* Merge previous clipboard contents with new text,
* then store the new string in the clipboard.
*/
BYTE
AddClip(STRPTR Buffer,LONG Size)
{
LONG Bytes;
APTR Store;
if(GetClipContents(Config -> ClipConfig -> ClipboardUnit,&Store,&Bytes))
{
struct IFFHandle *Handle;
BYTE Success = FALSE;
if(Handle = AllocIFF())
{
if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
{
InitIFFasClip(Handle);
if(!OpenIFF(Handle,IFFF_WRITE))
{
if(!PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
{
if(!PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN))
{
if(WriteChunkBytes(Handle,Store,Bytes) == Bytes)
{
if(WriteChunkBytes(Handle,Buffer,Size) == Size)
{
if(!PopChunk(Handle))
Success = TRUE;
}
}
}
}
if(Success)
{
if(PopChunk(Handle))
Success = FALSE;
}
CloseIFF(Handle);
}
CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
}
FreeIFF(Handle);
}
FreeVec(Store);
return(Success);
}
else
return(SaveClip(Buffer,Size));
}
/* SaveClip(STRPTR Buffer,LONG Size):
*
* Send a given text buffer to the clipboard.
*/
BYTE
SaveClip(STRPTR Buffer,LONG Size)
{
BYTE Success = FALSE;
if(Size > 0)
{
struct IFFHandle *Handle;
if(Handle = AllocIFF())
{
if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
{
InitIFFasClip(Handle);
if(!OpenIFF(Handle,IFFF_WRITE))
{
if(!PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
{
if(!PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN))
{
if(WriteChunkBytes(Handle,Buffer,Size) == Size)
{
if(!PopChunk(Handle))
Success = TRUE;
}
}
}
if(Success)
{
if(PopChunk(Handle))
Success = FALSE;
}
CloseIFF(Handle);
}
CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
}
FreeIFF(Handle);
}
}
return(Success);
}
/* LoadClip(STRPTR Buffer,LONG Size):
*
* Put the contents of the clipboard into a given
* buffer. Note that only the first FTXT chunk will
* be read. Since this code will only be called by
* the clipboard server process which serves the
* string gadget editing hook, this will hopefully
* not be fatal. If you want more data to be read,
* including multiple FTXT chunks, use the OpenClip(),
* GetClip(), CloseClip() combo above.
*/
LONG
LoadClip(STRPTR Buffer,LONG Size)
{
struct IFFHandle *Handle;
LONG Bytes = 0;
if(Handle = AllocIFF())
{
if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
{
InitIFFasClip(Handle);
if(!OpenIFF(Handle,IFFF_READ))
{
if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
{
if(!ParseIFF(Handle,IFFPARSE_SCAN))
{
struct ContextNode *ContextNode = CurrentChunk(Handle);
if(ContextNode -> cn_Type == ID_FTXT)
{
if(Size > ContextNode -> cn_Size)
Size = ContextNode -> cn_Size;
if(ReadChunkRecords(Handle,Buffer,Size,1))
Bytes = Size;
}
}
}
CloseIFF(Handle);
}
CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
}
FreeIFF(Handle);
}
return(Bytes);
}